2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程

您所在的位置:网站首页 react-router-dom v6官网 2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程

2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程

2023-04-10 07:08| 来源: 网络整理| 查看: 265

封面_掘金.png

原创声明-掘金.png

Electron是一个基于Chromium和Node.js,可以使用HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容Mac、Windows和 Linux。虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求。受限于浏览器的沙盒限制,网页应用无法满足某些场景下的使用需求,而桌面应用可以方便地读写本地文件、发起跨域请求、调用更多系统资源,再加上Web开发低成本、高效率的优势,这种方式越来越受到开发者的喜爱。

2022年2月,我发布了《2022新春版:手把手教你搭建Electron17+React17+Antd架构工程》,时隔一年,Electron24已经发布,React18、Antd5等很多前端框架、UI库、依赖包都有不同程度的更新,使用方法也发生了变化。因此再次更新一版,希望能够帮助各位省去摸索的时间,少走弯路,快速完成项目开发。

本文主要分享如何使用Electron和Create-React-App开发跨平台桌面客户端。React技术栈的小伙伴不要错过哟!

先睹为快

先看下目录了解本教程都有哪些内容。

1 Electron核心概念 • 1.1 主进程 • 1.2 渲染进程 • 1.3 预加载脚本(preload.js) 2 初始化项目 • 2.1 使用create-react-app新建项目 • 2.2 精简项目 3 Webpack配置 • 3.1 配置国内镜像源 • 3.2 暴露Webpack • 3.3 支持Sass/Scss • 3.4 支持Less • 3.5 支持Stylus • 3.6 设置路径别名 • 3.7 禁止build项目生成map文件 4 项目架构搭建 • 4.1 项目目录结构设计 • 4.2 关于样式命名规范 • 4.3 设置全局公用样式 5 引入Ant Design 5.x • 5.1 安装Ant Design • 5.2 设置Antd为中文语言 6 渲染进程开发 • 6.1 构建Login页面 • 6.2 构建Home页面 • 6.3 实现页面路由跳转 • 6.4 在React组件中实现页面路由跳转 • 6.5 在非React组件中实现页面路由跳转 7 集成Electron • 7.1 通过国内镜像加速安装Electron • 7.2 配置Electron • 7.3 启动Electron dev热更新模式 • 7.4 禁止开发环境启动时同时打开浏览器 8 主进程与渲染进程通信方法一:send与on/once • 8.1 主进程开发 • 8.2 preload.js开发 • 8.3 入口文件配置 • 8.4 渲染进程开发 • 8.5 打开Electron的DevTools • 8.6 运行效果 • 8.7 关于ipcRenderer.on/once • 8.8 为什么必须在preload里定义ipcRenderer.on/once 9 主进程与渲染进程通信方法二:invoke与handle • 9.1 主进程开发 • 9.2 入口文件配置 • 9.3 渲染进程开发 • 9.4 运行效果 10 打包Electron • 10.1 安装electron-builder • 10.2 配置electron-builder • 10.3 配置build版本的主入口 • 10.4 解决elecron-build编译过程中下载慢的问题 • 10.5 build Electron应用 • 10.6 解决nsis无法下载问题 • 10.7 build后的目录结构 11 常用配置 • 11.1 设置开发环境应用icon • 11.2 设置build版应用icon • 11.3 设置APP窗口大小 • 11.4 取消跨域限制 • 11.5 取消菜单栏 • 11.6 设置DevTools快捷键 • 11.7 禁止同时运行多个Electron程序 12 项目源码git 结束语 复制代码

本次分享Demo的主要依赖包版本:

Node.js 18.15.0 antd 5.4.0 create-react-app 5.0.1 react 18.2.0 react-router-dom 6.10.0 sass-loader 13.2.2 webpack 5.77.0 webpack-dev-server 4.13.2 concurrently 8.0.1 electron 24.0.0 electron-builder 23.6.0 less 4.1.3 less-loader 11.1.0 node-sass 8.0.0 stylus 0.59.0 stylus-loader 7.1.0 wait-on 7.0.1 复制代码

※注:

代码区域每行开头的:

"+" 表示新增

"-" 表示删除

"M" 表示修改

1 Electron核心概念

学习Electron最先要掌握的就是他的主进程与渲染进程概念。网上很多相关教程也进行了详细介绍,又是画关系图又是文字描述的。这里只想把最核心的内容总结一下,以最简单最通俗的方式让各位最快理解。

掌握三个核心概念即可:

1.1 主进程

每个Electron应用都有一个单一的主进程,作为应用程序的入口点。主进程运行在Node.js 环境,因此可以使用Node.js的所有API能力。主进程并不在浏览器环境中运行,因此不进行页面渲染。

1.2 渲染进程

渲染进程说白了就是平时的Web页面前端开发。每个Electron应用都会为每个打开的BrowserWindow生成一个单独的渲染器进程。但是渲染进程是无法直接调用Node.js的API的。

1.3 预加载脚本(preload.js)

为了让渲染进程与主进程进行通信从而形成一个整体,预加载脚本的作用就是他们之间的桥梁。预加载脚本与渲染进程共享同一个全局window,因此可以通过window来传递数据。但并不是简单地通过给window添加属性就能使用,以下方式是无法把preload.js共享给渲染进程使用的:

// 预加载脚本(preload.js) window.myAPI = { desktop: true } 复制代码 // 渲染进程 console.log(window.myAPI) // => undefined(获取不到) 复制代码

这是因为Electron的语境隔离(Context Isolation),使得预加载脚本与渲染进程的主要运行环境是隔离的,以避免将任何API都加入到渲染进程的网页中。

因此,需要使用contextBridge来安全地实现交互:

// 预加载脚本(preload.js) const { contextBridge } = require('electron') contextBridge.exposeInMainWorld('myAPI', { desktop: true }) 复制代码 // 渲染进程 console.log(window.myAPI) // => { desktop: true } (成功获取) 复制代码

以上方式就是通过contextBridge.exposeInMainWorld将preload.js中的myAPI数据共享给渲染进程的网页使用。

官网详细介绍:

www.electronjs.org/zh/docs/lat…

2 初始化项目 2.1 使用create-react-app新建项目

找个合适的目录,执行:

npx create-react-app electron-cra 复制代码

命令最后的electron-cra是项目的名称,可以自行更改。

编写教程时,create-react-app已经发布了5.0.1,如果一直报错:

you are running create-react-app 4.0.3 which is behind the latest release (5.0.1) 复制代码

说明你还在使用旧版本的create-react-app,需要先清除npx缓存,执行:

npx clear-npx-cache 复制代码

然后再执行之前的命令创建项目:

npx create-react-app electron-cra 复制代码

稍等片刻即可完成安装。安装完成后,可以使用npm或者yarn启动项目。

进入项目目录,并启动项目:

cd electron-cra yarn start (或者使用npm start) 复制代码

如果没有安装yarn,可执行以下命令全局安装:

npm install --global yarn 复制代码

yarn中文网站: yarn.bootcss.com/

启动后,可以通过以下地址访问项目:

http://localhost:3000/

2.1_ 新建项目.png

2.2 精简项目

接下来,删除用不到的文件,最简化项目。

├─ /node_modules ├─ /public | ├─ favicon.ico | ├─ index.html - | ├─ logo192.png - | ├─ logo512.png - | ├─ mainfest.json - | └─ robots.txt ├─ /src - | ├─ App.css | ├─ App.js - | ├─ App.test.js - | ├─ index.css | ├─ index.js - | ├─ logo.svg - | ├─ reportWebVitals.js - | └─ setupTests.js ├─ .gitignore ├─ package-lock.json ├─ package.json └─ README.md 复制代码

现在目录结构如下,清爽许多:

├─ /node_modules ├─ /public | ├─ favicon.ico | └─ index.html ├─ /src | ├─ App.js | └─ index.js ├─ .gitignore ├─ package-lock.json ├─ package.json └─ README.md 复制代码

以上文件删除后,页面会报错。这是因为相应的文件引用已不存在。需要继续修改代码,先让项目正常运行起来。

逐个修改以下文件,最终精简代码依次如下:

src/App.js:

function App() { return React-App } export default App 复制代码

src/index.js:

import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' const root = ReactDOM.createRoot(document.getElementById('root')) root.render() 复制代码

public/index.html:

React App You need to enable JavaScript to run this app. 复制代码

运行效果如下:

2.2_精简项目.png

3 Webpack配置 3.1 配置国内镜像源

npm和yarn默认是从国外源站拉取依赖包的,为提高下载速度和稳定性,建议配置为国内镜像源。

yarn registry国内镜像:

yarn config set registry https://registry.npmmirror.com 复制代码

npm registry国内镜像:

npm config set registry https://registry.npmmirror.com 复制代码

yarn node-sass国内镜像:

yarn config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/ 复制代码

npm node-sass国内镜像(仅限于npm < v9的版本):

npm config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/ 复制代码

※注: 从npm v9 版本开始,npm 命令限制了npm config set只能设置npm官方规定的config (docs.npmjs.com/cli/v9/usin… ~/.npmrc 文件的方式实现旧版本npm config set的效果。

据淘宝官方声明,原先的 npm.taobao.org 和 registry.npm.taobao.org 域名于2022年5月31日零时起停止服务。新域名如下:

【Web 站点】npmmirror.com

【Registry Endpoint】registry.npmmirror.com

官方公告原文:《【望周知】淘宝 NPM 镜像站喊你切换新域名啦》(zhuanlan.zhihu.com/p/430580607)

如果不清楚本地当前yarn或者npm的配置,可以执行以下命令查看:

yarn查看方法:

yarn config list 复制代码

npm查看方法:

npm config list 复制代码 3.2 暴露Webpack

create-react-app默认情况下未暴露配置文件。如果要更灵活地配置项目,需要将配置文件暴露出来。

执行以下命令,暴露配置文件:

yarn eject 复制代码

eject之前必须确保当前工程所有文件已提交git,否则会报以下错误:

Remove untracked files, stash or commit any changes, and try again. 复制代码

需要先在项目根目录下执行提交git:

git add . git commit -m "初始化项目(备注)" 复制代码

然后再执行:

yarn eject 复制代码

即可完成Webpack的暴露,这时项目里会多出来两个目录和若干个文件。具体变化如下:

+ ├─ /config ├─ /node_modules ├─ /public + ├─ /scripts ├─ /src ├─ .gitignore M ├─ package-lock.json M ├─ package.json └─ README.md 复制代码 3.3 支持Sass/Scss

eject后,虽然package.json以及webpack.config.js里有了sass相关代码,但是要正确使用Sass/Scss,还要再安装node-sass。

执行以下命令:

yarn add node-sass --dev 复制代码

安装完成后,项目已支持Sass/Scss。

3.4 支持Less

支持Less稍微多一点步骤,首先安装less和less-loader,执行:

yarn add less less-loader --dev 复制代码

然后修改config/webpack.config.js:

// style files regexes const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; + const lessRegex = /\.less$/; + const lessModuleRegex = /\.module\.less$/; ...(略) // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the // extensions .module.scss or .module.sass { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { mode: 'icss', }, }, 'sass-loader' ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass { test: sassModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { mode: 'local', getLocalIdent: getCSSModuleLocalIdent, }, }, 'sass-loader' ), + // 支持Less + { + test: lessRegex, + exclude: lessModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, + modules: { + mode: 'icss', + }, + }, + 'less-loader' + ), + sideEffects: true, + }, + { + test: lessModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, + modules: { + mode: 'local', + getLocalIdent: getCSSModuleLocalIdent, + }, + }, + 'less-loader' + ), + }, 复制代码

其实就把上面sass配置代码复制一遍,改成less。按照以上操作后,项目已支持Less。

3.5 支持Stylus

支持Stylus跟Less完全一样,首先安装stylus和stylus-loader,执行:

yarn add stylus stylus-loader --dev 复制代码

安装完成后,按照上一小节支持Less的方法,修改config/webpack.config.js:

// style files regexes const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; const lessRegex = /\.less$/; const lessModuleRegex = /\.module\.less$/; + const stylusRegex = /\.styl$/; + const stylusModuleRegex = /\.module\.styl$/; ...(略) + // 支持stylus + { + test: stylusRegex, + exclude: stylusModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, + modules: { + mode: 'icss', + }, + }, + 'stylus-loader' + ), + sideEffects: true, + }, + { + test:stylusModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, + modules: { + mode: 'local', + getLocalIdent: getCSSModuleLocalIdent, + }, + }, + 'stylus-loader' + ), + }, 复制代码

完成以上操作后,项目已支持Stylus。

3.6 设置路径别名

为了避免使用相对路径的麻烦,可以设置路径别名。

修改config/webpack.config.js:

alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web', // Allows for better profiling with ReactDevTools ...(isEnvProductionProfile && { 'react-dom$': 'react-dom/profiling', 'scheduler/tracing': 'scheduler/tracing-profiling', }), ...(modules.webpackAliases || {}), + '@': path.join(__dirname, '..', 'src'), }, 复制代码

这样在js代码开头的import路径中,直接使用@表示“src根目录”,不用去自己去数有多少个"../"了。

例如,src/app.js:

// 表示该文件当前路径下的app.styl(相对路径) import './app.styl' // 表示src/app.styl,等价于上面的文件地址(绝对路径) import '@/app.styl' 复制代码 3.7 禁止build项目生成map文件

map文件,即Javascript的source map文件,是为了解决被混淆压缩的js在调试的时候,能够快速定位到压缩前的源代码的辅助性文件。这个文件发布出去,会暴露源代码。因此,建议直接禁止build时生成map文件。

修改config/webpack.config.js,把shouldUseSourceMap的值改成false:

// Source maps are resource heavy and can cause out of memory issue for large source files. - // const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; + const shouldUseSourceMap =false; 复制代码 4 项目架构搭建 4.1 项目目录结构设计

项目目录结构可根据项目实际灵活制定。这里分享下我常用的结构,主要分为公用模块目录、组件模块目录、页面模块目录、路由配置目录等几个部分,让项目结构更加清晰合理。

├─ /config


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3